home *** CD-ROM | disk | FTP | other *** search
/ .net 2002 March / DotNetMagazine-Issue107-Coverdisc-NET107-02-03-PCMac.bin / pc / PC Software / free_browsing / DavesQckSearchDbar3-14 / dqsd.exe / calculate.js < prev    next >
Text File  |  2002-01-05  |  5KB  |  223 lines

  1. // offline calculator
  2. function calculate(expr)
  3. {
  4.   if (expr.match(/=ERR$/))
  5.     return;
  6.  
  7.   try
  8.   {
  9.     with(Math)
  10.     {
  11.       var answer = eval(expr);
  12.       if (typeof(answer) == "number")
  13.       {
  14.         // for the sake of pretty decimal numbers,
  15.         // round numbers that are very close to a ten-millionth
  16.         if (abs(answer) >= 0.001 &&
  17.             abs(round(answer * 1e+7) - answer * 1e+7) < 0.001)
  18.           answer = round(answer * 1e+7)/1e+7;
  19.       }
  20.       document.deff.q.value = answer;
  21.     }
  22.   }
  23.   catch (exception)
  24.   {
  25.     document.deff.q.value = expr + "=ERR=";
  26.   }
  27.   document.deff.q.createTextRange().select();
  28.  
  29.   savevars();
  30. }
  31.  
  32. // based log functions
  33. function log10(n) { return ln(n)/ln10; }
  34. function log2(n) { return ln(n)/ln2; }
  35.  
  36. // hex conversion for use in calculator
  37. function hex(i)
  38. {
  39.   hexChars = "0123456789abcdef";
  40.   var h = "";
  41.   var n = 256;
  42.  
  43.   while (i < 0)
  44.   {
  45.      if (i + n / 16 > 0) { i += n; break; }
  46.      n = n * n;
  47.   }
  48.  
  49.   while (i > 0)
  50.   {
  51.      h = hexChars.charAt(i % 16) + h;
  52.      i = Math.floor(i / 16);
  53.   }
  54.  
  55.   if (h == "")
  56.      h = "0";
  57.  
  58.   return "0x" + h;
  59. }
  60.  
  61. // octal conversion for use in calculator
  62. function oct(i)
  63. {
  64.   octChars = "01234567";
  65.   var h = "";
  66.   var n = 512;
  67.  
  68.   while (i < 0)
  69.   {
  70.      if (i + n / 8 > 0) { i += n; break; }
  71.      n = n * n;
  72.   }
  73.  
  74.   while (i > 0)
  75.   {
  76.      h = octChars.charAt(i % 8) + h;
  77.      i = Math.floor(i / 8);
  78.   }
  79.  
  80.   if (h == "")
  81.      h = "0";
  82.  
  83.   return "0" + h;
  84. }
  85.  
  86. // binary conversion for use in calculator
  87. function bin(i)
  88. {
  89.   binChars = "01";
  90.   var h = "";
  91.   var n = 16;
  92.  
  93.   while (i < 0)
  94.   {
  95.      if (i + n / 2 > 0) { i += n; break; }
  96.      n = n * n;
  97.   }
  98.  
  99.   while (i > 0)
  100.   {
  101.      h = binChars.charAt(i % 2) + h;
  102.      i = Math.floor(i / 2);
  103.   }
  104.  
  105.   if (h == "")
  106.      h = "0";
  107.  
  108.   return h;
  109. }
  110.  
  111.  
  112. // detect numeric math expressions to execute right away
  113. function mathexp(t)
  114. {
  115.   // chop out variables
  116.   var noconst = t.replace(/\b(PI|E|LOG2E|LOG10E|LN2|LN10|SQRT2|SQRT1_2|pi)\b/g, "_");
  117.   // experiment: also allow "longvarname="
  118.   var noconst = noconst.replace(/^[a-zA-Z_]+\s*=/, "a=");
  119.   // it's only an expression if it ends with a digit, paren, or variable
  120.   if (!noconst.match(/\b[a-z]$|[_\d\)]$/)) return false;
  121.   // chop out function names
  122.   var nofunc = noconst.replace(/\b(ln|log10|log2|hex|oct|bin|abs|acos|asin|atan|atan2|ceil|cos|exp|floor|log|max|min|pow|random|round|sin|sqrt|tan)\(/g, "(");
  123.   // it's only an expression if it begins with a digit, paren, or variable - or a minus
  124.   if (!nofunc.match(/^[a-z_]\b|^[x\d\-\.\(]/)) return false;
  125.   // detect numbers
  126.   var nonum = nofunc.replace(/\b(\d+(\.\d*)?)([eE][+-]?\d+)?\b/g, "1");
  127.   var nonum = nonum.replace(/(\.\d+)([eE][+-]?\d+)?\b/g, "1");
  128.   // remove spsaces
  129.   var nospace = nonum.replace(/\s/g, "");
  130.   // only operators and recognized things are allowed
  131.   if (!nospace.match(/^[1_a-z\*\-\+\/\(\),=]+$/)) return false;
  132.   // constants cannot touch
  133.   if (nospace.match(/[1_a-z\)][1_a-z\(]/)) return false;
  134.   // operators cannot touch
  135.   if (nospace.match(/[\*\-\+\/][\*\+\/=]/)) return false;
  136.   // parens must match
  137.   var paren = 0;
  138.   var eq = 0;
  139.   var i;
  140.   for (i = nospace.length - 1; i >= 0; i--)
  141.   {
  142.     var ch = nospace.charAt(i);
  143.     if (eq == 1)
  144.     {
  145.       if (ch < 'a' || ch > 'z') return false;
  146.     }
  147.     else
  148.     {
  149.       if (ch >= 'a' && ch <= 'z' && eval("typeof " + ch) == "undefined") return false;
  150.     }
  151.     if (ch == '=') { eq++; }
  152.     if (ch == ')') { paren++; }
  153.     if (ch == '(') { paren--; }
  154.     if (paren < 0) return false;
  155.     if (eq > 1) return false;
  156.   }
  157.  
  158.   // looks like an expression: we can calc it
  159.   calculate(t);
  160.   return true;
  161. }
  162.  
  163.  
  164. function savevars()
  165. {
  166.   var savetext = "";
  167.   for (var ii = 'a'.charCodeAt(0); ii <= 'z'.charCodeAt(0); ii++)
  168.   {
  169.     var varname = String.fromCharCode(ii);
  170.     var vartype = eval("typeof " + varname);
  171.     if (vartype == "number" || vartype == "string")
  172.     {
  173.        savetext += varname + "\t" + vartype + "\t" + escape(eval(varname)) + "\r\n";
  174.     }
  175.   }
  176.   for (var ii = 'A'.charCodeAt(0); ii <= 'Z'.charCodeAt(0); ii++)
  177.   {
  178.     var varname = String.fromCharCode(ii);
  179.     var vartype = eval("typeof " + varname);
  180.     if (vartype == "number" || vartype == "string")
  181.     {
  182.        savetext += varname + "\t" + vartype + "\t" + escape(eval(varname)) + "\r\n";
  183.     }
  184.   }
  185.   writeFile("calcmem", savetext);
  186. }
  187.  
  188. function loadvars()
  189. {
  190.   var values = readTabDelimitedFile("calcmem")
  191.   for (var ii = 0; ii < values.length; ii++)
  192.   {
  193.     var value = values[ii];
  194.     if (value.length == 3)
  195.     {
  196.       if (value[1] == "number")
  197.       {
  198.         eval(value[0] + " = " + unescape(value[2]));
  199.       }
  200.       else if (value[1] == "string")
  201.       {
  202.         var strval = unescape(value[2]);
  203.         eval(value[0] + " = strval");
  204.       }
  205.     }
  206.   }
  207. }
  208.  
  209. loadvars();
  210.  
  211. // constants for use in calculator
  212. pi = Math.PI;
  213. ln10 = Math.LN10;
  214. ln2 = Math.LN2;
  215. log10e = Math.LOG10E;
  216. log2e = Math.LOG2E;
  217. sqrt1_2 = Math.SQRT1_2;
  218. sqrt2 = Math.SQRT2;
  219. ln = Math.log;
  220. e = Math.exp(1);
  221.  
  222.  
  223.